import OpenAI from 'openai';
import * as dotenv from 'dotenv';
// 加载环境变量
dotenv.config();

import { CONFIG } from '../utils/config';

/**
 * 支持的Deepseek模型类型
 */
export enum DeepseekModel {
  CHAT = 'deepseek-chat',      // DeepSeek-V3-0324
  REASONER = 'deepseek-reasoner' // DeepSeek-R1-0528
}

/**
 * 聊天消息角色
 */
export enum ChatRole {
  SYSTEM = 'system',
  USER = 'user',
  ASSISTANT = 'assistant'
}

/**
 * 聊天消息接口
 */
export interface ChatMessage {
  role: ChatRole;
  content: string;
}

/**
 * 聊天请求选项
 */
export interface ChatOptions {
  temperature?: number;  // 温度参数，控制随机性 (0-2)
  topP?: number;        // Top-p 采样，控制输出多样性 (0-1)
  maxTokens?: number;   // 最大输出token数
  stream?: boolean;     // 是否使用流式输出
}

/**
 * Deepseek API服务类
 * 提供对Deepseek模型的访问功能，使用与OpenAI兼容的API格式
 */
export class DeepseekService {
  private client: OpenAI;
  private readonly baseUrl = 'https://api.deepseek.com';

  /**
   * 构造函数
   * @param apiKey Deepseek API密钥，默认从配置中获取
   */
  constructor(apiKey?: string) {
    // 从配置或参数中获取API密钥
    const key = apiKey || CONFIG.DEEPSEEK_API_KEY || process.env.DEEPSEEK_API_KEY;

    if (!key) {
      throw new Error('缺少Deepseek API密钥，请在配置中设置DEEPSEEK_API_KEY或者通过构造函数提供');
    }

    // 初始化OpenAI客户端
    this.client = new OpenAI({
      apiKey: key,
      baseURL: this.baseUrl
    });
  }

  /**
   * 获取模型默认的最大输出token数
   * @param model 模型类型
   * @returns 默认的最大输出token数
   */
  private getDefaultMaxTokens(model: DeepseekModel): number {
    switch (model) {
      case DeepseekModel.CHAT:
        return 4000; // deepseek-chat 默认4K
      case DeepseekModel.REASONER:
        return 32000; // deepseek-reasoner 默认32K
      default:
        return 4000; // 默认情况下使用4K
    }
  }

  /**
   * 发送聊天请求并获取回复
   * @param messages 聊天消息数组
   * @param model 使用的模型，默认为chat模型
   * @param options 聊天选项
   * @returns 聊天回复内容
   */
  async chat(
    messages: ChatMessage[],
    model: DeepseekModel = DeepseekModel.CHAT,
    options: ChatOptions = {}
  ): Promise<string> {
    try {
      // 设置默认选项，根据模型类型设置默认的maxTokens
      const defaultMaxTokens = this.getDefaultMaxTokens(model);

      const chatOptions = {
        temperature: 0.7,
        topP: 0.9,
        maxTokens: defaultMaxTokens,
        stream: false,
        ...options
      };

      console.log(`使用模型 ${model} 发送请求，温度: ${chatOptions.temperature}, 最大Token: ${chatOptions.maxTokens}`);

      // 发送聊天请求
      const response = await this.client.chat.completions.create({
        model: model,
        messages: messages as any,
        temperature: chatOptions.temperature,
        top_p: chatOptions.topP,
        max_tokens: chatOptions.maxTokens,
        stream: false
      });

      // 返回回复内容
      const content = response.choices[0].message.content || '';
      console.log(`收到回复，总长度: ${content.length} 字符`);

      return content;
    } catch (error: any) {
      console.error('Deepseek API请求失败:', error.message);
      throw new Error(`Deepseek API请求失败: ${error.message}`);
    }
  }

  /**
   * 发送聊天请求并获取流式回复
   * @param messages 聊天消息数组
   * @param onUpdate 流式更新回调函数
   * @param model 使用的模型，默认为chat模型
   * @param options 聊天选项（不包括stream，强制为true）
   */
  async chatStream(
    messages: ChatMessage[],
    onUpdate: (content: string, done: boolean) => void,
    model: DeepseekModel = DeepseekModel.CHAT,
    options: Omit<ChatOptions, 'stream'> = {}
  ): Promise<void> {
    try {
      // 设置默认选项，根据模型类型设置默认的maxTokens
      const defaultMaxTokens = this.getDefaultMaxTokens(model);

      const chatOptions = {
        temperature: 0.7,
        topP: 0.9,
        maxTokens: defaultMaxTokens,
        ...options
      };

      // 发送流式聊天请求
      const stream = await this.client.chat.completions.create({
        model: model,
        messages: messages as any,
        temperature: chatOptions.temperature,
        top_p: chatOptions.topP,
        max_tokens: chatOptions.maxTokens,
        stream: true
      });

      let content = '';

      // 处理流式响应 - stream类型在TypeScript中需要直接处理
      for await (const chunk of stream as any) {
        const chunkContent = chunk.choices[0]?.delta?.content || '';
        content += chunkContent;
        onUpdate(content, false);
      }

      // 完成时回调
      onUpdate(content, true);
    } catch (error: any) {
      console.error('Deepseek API流式请求失败:', error.message);
      throw new Error(`Deepseek API流式请求失败: ${error.message}`);
    }
  }

  /**
   * 创建系统消息
   * @param content 消息内容
   * @returns 系统消息对象
   */
  static systemMessage(content: string): ChatMessage {
    return { role: ChatRole.SYSTEM, content };
  }

  /**
   * 创建用户消息
   * @param content 消息内容
   * @returns 用户消息对象
   */
  static userMessage(content: string): ChatMessage {
    return { role: ChatRole.USER, content };
  }

  /**
   * 创建助手消息
   * @param content 消息内容
   * @returns 助手消息对象
   */
  static assistantMessage(content: string): ChatMessage {
    return { role: ChatRole.ASSISTANT, content };
  }
} 